﻿using System.Reflection;
using System.Web.Mvc;
using AutoMapper;
using Castle.Facilities.FactorySupport;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using CommonServiceLocator.WindsorAdapter;
using Microsoft.Practices.ServiceLocation;
using MvcContrib.Castle;
using ThunderJob.Bootstrapper.Configuration;
using ThunderJob.Bootstrapper.Extensions;
using ThunderJob.Controllers.Home;
using ThunderJob.Domain;
using ThunderJob.Domain.Services;
using ThunderJob.Persistence.Repositories;

namespace ThunderJob.Bootstrapper.Dependency
{
    public class DependencyRegistrar
    {
        private static bool dependenciesRegistered;
        private static readonly object sync = new object();

        private static readonly IWindsorContainer Container = new WindsorContainer();

        private void Register()
        {
            RegisterControllers();
            RegisterComponents();
            RegisterAutoMapperEngine();
            RegisterConfigurationTasks();
            RegisterServiceLocator();
        }

        private void RegisterComponents()
        {
            Container.Register(AllTypes
                                   .FromAssembly(typeof(ReclutarPersonal).Assembly)
                                   .Where(x => x.Namespace.Contains(".Services"))
                                   .Configure(c => c.LifeStyle.Transient)
                                   .WithService.FirstInterface());

            Container.Register(AllTypes
                       .FromAssembly(typeof(EmpresaRepository).Assembly)
                       .Where(x => x.Namespace.Contains(".Repositories"))
                       .Configure(c => c.LifeStyle.Transient)
                       .WithService.FirstNonGenericCoreInterface(typeof(Empresa).Namespace));
        }

        private void RegisterAutoMapperEngine()
        {
            Container.AddFacility<FactorySupportFacility>();
            Container.Register(Component.For<IMappingEngine>()
                                   .UsingFactoryMethod(() => Mapper.Engine));
        }

        private void RegisterControllers()
        {
            ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(Container));
            Container.RegisterControllers(typeof(HomeController).Assembly);
        }


        private void RegisterConfigurationTasks()
        {
            Container.Register(AllTypes.FromAssembly(Assembly.GetExecutingAssembly())
                                   .BasedOn<IConfigurationTask>()
                                   .Configure(c => c.LifeStyle.Transient));

        }

        private void RegisterServiceLocator()
        {
            ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(Container));
        }

        public static void RegisterSingletonInstance<T>(T instance)
        {
            Container.Register(Component.For<T>()
                       .Instance(instance)
                       .LifeStyle.Singleton);
        }

        public static void EnsureRegistered()
        {
            if (!dependenciesRegistered)
            {
                lock (sync)
                {
                    if (!dependenciesRegistered)
                    {
                        new DependencyRegistrar().Register();
                        dependenciesRegistered = true;
                    }
                }
            }
        }
    }
}